home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / gas_251.zip / bin_251 / bfd / coff-sparc.c < prev    next >
C/C++ Source or Header  |  1994-10-04  |  11KB  |  278 lines

  1. /* BFD back-end for Sparc COFF files.
  2.    Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
  3.    Written by Cygnus Support.
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "bfd.h"
  22. #include "sysdep.h"
  23. #include "libbfd.h"
  24. #include "obstack.h"
  25. #include "coff/sparc.h"
  26. #include "coff/internal.h"
  27. #include "libcoff.h"
  28.  
  29. #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
  30.  
  31. #define BADMAG(x) ((x).f_magic != SPARCMAGIC && (x).f_magic != LYNXCOFFMAGIC)
  32.  
  33. /* The page size is a guess based on ELF.  */
  34. #define COFF_PAGE_SIZE 0x10000
  35.  
  36. enum reloc_type
  37.   {
  38.     R_SPARC_NONE = 0,
  39.     R_SPARC_8,        R_SPARC_16,        R_SPARC_32, 
  40.     R_SPARC_DISP8,    R_SPARC_DISP16,        R_SPARC_DISP32, 
  41.     R_SPARC_WDISP30,    R_SPARC_WDISP22,
  42.     R_SPARC_HI22,    R_SPARC_22,
  43.     R_SPARC_13,        R_SPARC_LO10,
  44.     R_SPARC_GOT10,    R_SPARC_GOT13,        R_SPARC_GOT22,
  45.     R_SPARC_PC10,    R_SPARC_PC22,
  46.     R_SPARC_WPLT30,
  47.     R_SPARC_COPY,
  48.     R_SPARC_GLOB_DAT,    R_SPARC_JMP_SLOT,
  49.     R_SPARC_RELATIVE,
  50.     R_SPARC_UA32,
  51.     R_SPARC_max
  52.   };
  53.  
  54. #if 0
  55. static CONST char *CONST reloc_type_names[] =
  56. {
  57.   "R_SPARC_NONE",
  58.   "R_SPARC_8",        "R_SPARC_16",        "R_SPARC_32",
  59.   "R_SPARC_DISP8",    "R_SPARC_DISP16",    "R_SPARC_DISP32",
  60.   "R_SPARC_WDISP30",    "R_SPARC_WDISP22",
  61.   "R_SPARC_HI22",    "R_SPARC_22",
  62.   "R_SPARC_13",        "R_SPARC_LO10",
  63.   "R_SPARC_GOT10",    "R_SPARC_GOT13",    "R_SPARC_GOT22",
  64.   "R_SPARC_PC10",    "R_SPARC_PC22",
  65.   "R_SPARC_WPLT30",
  66.   "R_SPARC_COPY",
  67.   "R_SPARC_GLOB_DAT",    "R_SPARC_JMP_SLOT",
  68.   "R_SPARC_RELATIVE",
  69.   "R_SPARC_UA32",
  70. };
  71. #endif
  72.  
  73. /* This is stolen pretty directly from elf.c.  */
  74. static bfd_reloc_status_type
  75. bfd_coff_generic_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR,
  76.                 asection *, bfd *, char **));
  77.  
  78. static bfd_reloc_status_type
  79. bfd_coff_generic_reloc (abfd, reloc_entry, symbol, data, input_section,
  80.             output_bfd, error_message)
  81.      bfd *abfd;
  82.      arelent *reloc_entry;
  83.      asymbol *symbol;
  84.      PTR data;
  85.      asection *input_section;
  86.      bfd *output_bfd;
  87.      char **error_message;
  88. {
  89.   if (output_bfd != (bfd *) NULL
  90.       && (symbol->flags & BSF_SECTION_SYM) == 0
  91.       && reloc_entry->addend == 0)
  92.     {
  93.       reloc_entry->address += input_section->output_offset;
  94.       return bfd_reloc_ok;
  95.     }
  96.  
  97.   return bfd_reloc_continue;
  98. }
  99.  
  100. static reloc_howto_type coff_sparc_howto_table[] = 
  101. {
  102.   HOWTO(R_SPARC_NONE,    0,0, 0,false,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_NONE",    false,0,0x00000000,true),
  103.   HOWTO(R_SPARC_8,       0,0, 8,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_8",       false,0,0x000000ff,true),
  104.   HOWTO(R_SPARC_16,      0,1,16,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_16",      false,0,0x0000ffff,true),
  105.   HOWTO(R_SPARC_32,      0,2,32,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_32",      false,0,0xffffffff,true),
  106.   HOWTO(R_SPARC_DISP8,   0,0, 8,true, 0,complain_overflow_signed,  bfd_coff_generic_reloc,"R_SPARC_DISP8",   false,0,0x000000ff,true),
  107.   HOWTO(R_SPARC_DISP16,  0,1,16,true, 0,complain_overflow_signed,  bfd_coff_generic_reloc,"R_SPARC_DISP16",  false,0,0x0000ffff,true),
  108.   HOWTO(R_SPARC_DISP32,  0,2,32,true, 0,complain_overflow_signed,  bfd_coff_generic_reloc,"R_SPARC_DISP32",  false,0,0x00ffffff,true),
  109.   HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed,  bfd_coff_generic_reloc,"R_SPARC_WDISP30", false,0,0x3fffffff,true),
  110.   HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed,  bfd_coff_generic_reloc,"R_SPARC_WDISP22", false,0,0x003fffff,true),
  111.   HOWTO(R_SPARC_HI22,   10,2,22,false,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_HI22",    false,0,0x003fffff,true),
  112.   HOWTO(R_SPARC_22,      0,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_22",      false,0,0x003fffff,true),
  113.   HOWTO(R_SPARC_13,      0,2,13,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_13",      false,0,0x00001fff,true),
  114.   HOWTO(R_SPARC_LO10,    0,2,10,false,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_LO10",    false,0,0x000003ff,true),
  115.   HOWTO(R_SPARC_GOT10,   0,2,10,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT10",   false,0,0x000003ff,true),
  116.   HOWTO(R_SPARC_GOT13,   0,2,13,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT13",   false,0,0x00001fff,true),
  117.   HOWTO(R_SPARC_GOT22,  10,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT22",   false,0,0x003fffff,true),
  118.   HOWTO(R_SPARC_PC10,    0,2,10,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC10",    false,0,0x000003ff,true),
  119.   HOWTO(R_SPARC_PC22,    0,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC22",    false,0,0x003fffff,true),
  120.   HOWTO(R_SPARC_WPLT30,  0,0,00,false,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_WPLT30",  false,0,0x00000000,true),
  121.   HOWTO(R_SPARC_COPY,    0,0,00,false,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_COPY",    false,0,0x00000000,true),
  122.   HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_GLOB_DAT",false,0,0x00000000,true),
  123.   HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_JMP_SLOT",false,0,0x00000000,true),
  124.   HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_RELATIVE",false,0,0x00000000,true),
  125.   HOWTO(R_SPARC_UA32,    0,0,00,false,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_UA32",    false,0,0x00000000,true),
  126. };
  127.  
  128. struct coff_reloc_map {
  129.   unsigned char bfd_reloc_val;
  130.   unsigned char coff_reloc_val;
  131. };
  132.  
  133. static CONST struct coff_reloc_map sparc_reloc_map[] =
  134. {
  135.   { BFD_RELOC_NONE, R_SPARC_NONE, },
  136.   { BFD_RELOC_16, R_SPARC_16, },
  137.   { BFD_RELOC_8, R_SPARC_8 },
  138.   { BFD_RELOC_8_PCREL, R_SPARC_DISP8 },
  139.   { BFD_RELOC_CTOR, R_SPARC_32 }, /* @@ Assumes 32 bits.  */
  140.   { BFD_RELOC_32, R_SPARC_32 },
  141.   { BFD_RELOC_32_PCREL, R_SPARC_DISP32 },
  142.   { BFD_RELOC_HI22, R_SPARC_HI22 },
  143.   { BFD_RELOC_LO10, R_SPARC_LO10, },
  144.   { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 },
  145.   { BFD_RELOC_SPARC22, R_SPARC_22 },
  146.   { BFD_RELOC_SPARC13, R_SPARC_13 },
  147.   { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 },
  148.   { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 },
  149.   { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 },
  150.   { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 },
  151.   { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 },
  152.   { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 },
  153.   { BFD_RELOC_SPARC_COPY, R_SPARC_COPY },
  154.   { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT },
  155.   { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT },
  156.   { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE },
  157.   { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 },
  158.   /*  { BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */
  159. };
  160.  
  161. static CONST struct reloc_howto_struct *
  162. coff_sparc_reloc_type_lookup (abfd, code)
  163.      bfd *abfd;
  164.      bfd_reloc_code_real_type code;
  165. {
  166.   int i;
  167.   for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct coff_reloc_map); i++)
  168.     {
  169.       if (sparc_reloc_map[i].bfd_reloc_val == code)
  170.     return &coff_sparc_howto_table[(int) sparc_reloc_map[i].coff_reloc_val];
  171.     }
  172.   return 0;
  173. }
  174. #define coff_bfd_reloc_type_lookup    coff_sparc_reloc_type_lookup
  175.  
  176. static void
  177. rtype2howto (cache_ptr, dst)
  178.      arelent *cache_ptr;
  179.      struct internal_reloc *dst;
  180. {
  181.   BFD_ASSERT (dst->r_type < (unsigned int) R_SPARC_max);
  182.   cache_ptr->howto = &coff_sparc_howto_table[dst->r_type];
  183. }
  184.  
  185. #define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
  186.  
  187. #define SWAP_IN_RELOC_OFFSET    bfd_h_get_32
  188. #define SWAP_OUT_RELOC_OFFSET    bfd_h_put_32
  189. /* This is just like the standard one, except for the addition of the
  190.    last line, the adjustment of the addend.  */
  191. #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)                \
  192.   {                                                             \
  193.     coff_symbol_type *coffsym = (coff_symbol_type *) NULL;      \
  194.     if (ptr && bfd_asymbol_bfd (ptr) != abfd)                   \
  195.       coffsym = (obj_symbols (abfd)                             \
  196.                  + (cache_ptr->sym_ptr_ptr - symbols));         \
  197.     else if (ptr)                                               \
  198.       coffsym = coff_symbol_from (abfd, ptr);                   \
  199.     if (coffsym != (coff_symbol_type *) NULL                    \
  200.         && coffsym->native->u.syment.n_scnum == 0)              \
  201.       cache_ptr->addend = 0;                                    \
  202.     else if (ptr && bfd_asymbol_bfd (ptr) == abfd               \
  203.              && ptr->section != (asection *) NULL)              \
  204.       cache_ptr->addend = - (ptr->section->vma + ptr->value);   \
  205.     else                                                        \
  206.       cache_ptr->addend = 0;                                    \
  207.     cache_ptr->addend += reloc.r_offset;            \
  208.   }
  209.  
  210. /* Clear the r_spare field in relocs.  */
  211. #define SWAP_OUT_RELOC_EXTRA(abfd,src,dst) \
  212.   do { \
  213.        dst->r_spare[0] = 0; \
  214.        dst->r_spare[1] = 0; \
  215.      } while (0)
  216.  
  217. #define __A_MAGIC_SET__
  218.  
  219. /* Enable Sparc-specific hacks in coffcode.h. */
  220.  
  221. #define COFF_SPARC
  222.  
  223. #include "coffcode.h"
  224.  
  225. const bfd_target
  226. #ifdef TARGET_SYM
  227.   TARGET_SYM =
  228. #else
  229.   sparccoff_vec =
  230. #endif
  231. {
  232. #ifdef TARGET_NAME
  233.   TARGET_NAME,
  234. #else
  235.   "coff-sparc",            /* name */
  236. #endif
  237.   bfd_target_coff_flavour,
  238.   true,            /* data byte order is big */
  239.   true,            /* header byte order is big */
  240.  
  241.   (HAS_RELOC | EXEC_P |        /* object flags */
  242.    HAS_LINENO | HAS_DEBUG |
  243.    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
  244.  
  245.   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
  246.   '_',                /* leading underscore */
  247.   '/',                /* ar_pad_char */
  248.   15,                /* ar_max_namelen */
  249.  
  250.   2,                /* minimum alignment power */
  251.   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  252.      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  253.      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
  254.   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  255.      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  256.      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
  257.  
  258. /* Note that we allow an object file to be treated as a core file as well. */
  259.     {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
  260.        bfd_generic_archive_p, coff_object_p},
  261.     {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
  262.        bfd_false},
  263.     {bfd_false, coff_write_object_contents, /* bfd_write_contents */
  264.        _bfd_write_archive_contents, bfd_false},
  265.  
  266.      BFD_JUMP_TABLE_GENERIC (coff),
  267.      BFD_JUMP_TABLE_COPY (coff),
  268.      BFD_JUMP_TABLE_CORE (_bfd_nocore),
  269.      BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
  270.      BFD_JUMP_TABLE_SYMBOLS (coff),
  271.      BFD_JUMP_TABLE_RELOCS (coff),
  272.      BFD_JUMP_TABLE_WRITE (coff),
  273.      BFD_JUMP_TABLE_LINK (coff),
  274.      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
  275.  
  276.   COFF_SWAP_TABLE,
  277. };
  278.